import Konva from "konva";
import { Draw } from "../../../Draw/Draw";
import { parseLinePoints } from "../../../Utils";
import { KONVA_LINE_NAME } from "../../../Config";
import { IKonva } from "../../../Interface/IKonva";
import { addGuidLine, clearGuidLine } from "./group-guid-line";

/**
 * Konva Graph 基类移动事件
 */
export function groupDragMove(e: IKonva.Event, draw: Draw) {
  e.cancelBubble = true;

  const layer = draw.getLayer();
  if (!layer) return;

  // 清空对齐辅助线
  clearGuidLine(draw);

  // 添加对其辅助线
  addGuidLine(e, draw);

  const currentGroup = <Konva.Group>e.currentTarget;
  // 支持一个状态下进行 Line 的移动

  lineFlowMove(currentGroup.id(), draw);

  // 同步位置状态 - 多选状态下移动某一个 其他元素需要同步
  const selected = draw.getKonvaGraph().getSelected();
  if (!selected.length) return;

  // 拖动元素没被选中，则不处理，不然拖拽没被选中的元素，而其他元素被选中，则会报 warning
  if (!selected.includes(<Konva.Group>e.currentTarget)) return;

  // 取当前 拖动元素 的 sx sy
  const { sx, sy } = e.currentTarget.attrs;
  // 取当前位置求差
  const dx = e.currentTarget.x() - sx;
  const dy = e.currentTarget.y() - sy;

  // 所有的 选中元素 都偏移相同的 dx dy
  selected.forEach((g) => {
    if (g.id() === e.currentTarget.id()) return;
    g.setAttrs({ x: g.getAttr("sx") + dx, y: g.getAttr("sy") + dy });
    lineFlowMove(g.id(), draw);
  });
}

function lineFlowMove(id: string, draw: Draw) {
  const layer = draw.getLayer()!;
  // 获取 group 的末态坐标
  const group = layer.findOne(`#${id}`);
  if (!group) return;

  const { x, y, realWidth, realHeight, width, height } = group.attrs;
  const w = realWidth || width;
  const h = realHeight || height;

  const points = [
    { order: 1, x: x + w / 2, y: y },
    { order: 2, x: x + w, y: y + h / 2 },
    { order: 3, x: x + w / 2, y: y + h },
    { order: 4, x: x, y: y + h / 2 },
  ];

  // Line 跟随移动
  const lines = <Konva.Line[]>layer.find(`.${KONVA_LINE_NAME}`);
  const currentLines = lines.filter(
    (line) =>
      // 找到 startShape endShape  为当前 ID 的 Line
      line.attrs.startShape?.id === id || line.attrs.endShape?.id === id
  );

  if (!currentLines.length) return;

  // 不然 拿到当前移动的元素的 x y width height ，重新计算 order 点位的 x y 重新计算 line points
  currentLines.forEach((line) => {
    // 解析 startShape endShape
    const { startShape, endShape } = line.attrs;
    if (startShape && startShape.id === id) {
      // 取 order、ID
      const order = startShape.order;
      // 计算对应 order 的新坐标
      const point = points.find((p) => p.order === order)!;
      // 更新 line points 字段
      const controlArr = parseLinePoints(line?.attrs.points);
      const lx = line.x();
      const ly = line.y();
      const newPoints: number[] = [];
      controlArr.forEach((item, index) => {
        if (index === 0) {
          newPoints.push(point.x - lx, point.y - ly);
        } else {
          newPoints.push(...item);
        }
      });
      line.points(newPoints);
    }
    if (endShape && endShape.id === id) {
      const order = endShape.order;
      // 计算对应 order 的新坐标
      const point = points.find((p) => p.order === order)!;
      // 更新 line points 字段
      const controlArr = parseLinePoints(line?.attrs.points);
      const lx = line.x();
      const ly = line.y();
      const newPoints: number[] = [];
      controlArr.forEach((item, index) => {
        if (index === controlArr.length - 1) {
          newPoints.push(point.x - lx, point.y - ly);
        } else {
          newPoints.push(...item);
        }
      });
      line.points(newPoints);
    }
  });
}
